package org.dna;

import org.apache.log4j.Logger;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.Session;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
import org.apache.wicket.protocol.http.WebApplication;
import org.dna.metronomo.persistence.IActivityDAO;
import org.dna.metronomo.persistence.IUserDAO;
import org.dna.wickwtui.LoginPage;
import org.dna.wickwtui.MetroPage;
import org.dna.wickwtui.activities.ManageActivityPage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Application object for your web application. If you want to run this
 * application without deploying, run the Start class.
 * 
 * @see wicket.myproject.Start#main(String[])
 */
public class MetroApplication extends WebApplication {

    private static final Logger LOG = Logger.getLogger(MetroApplication.class);

    public static final class MetroAuthorizationStrategy implements
            IAuthorizationStrategy, IUnauthorizedComponentInstantiationListener {

        public boolean isActionAuthorized(Component component, Action action) {
            if (action.equals(Component.RENDER)) {
                Class<? extends Component> c = component.getClass();
                UserRoles userRoles = c.getAnnotation(UserRoles.class);
                if (userRoles != null) {
                    User user = MetroSession.get().getUser();
                    return (user != null && user.hasRole(userRoles.value()));
                }
            }
            return true;
        }

        public <T extends Component> boolean isInstantiationAuthorized(
                Class<T> componentClass) {
            if (MetroPage.class.isAssignableFrom(componentClass)) {
                return MetroSession.get().isAuthenticated();
            }
            return true;
        }

        public void onUnauthorizedInstantiation(Component component) {
            throw new RestartResponseAtInterceptPageException(LoginPage.class);
        }
    }
    private ApplicationContext m_context;

    /**
     * Constructor
     */
    public MetroApplication() {
        super();
    }

    public static MetroApplication get() {
        return (MetroApplication) Application.get();
    }

    /*
     * Here init the Spring context
     */
    @Override
    protected void init() {
        super.init();
        m_context = new ClassPathXmlApplicationContext("spring-context.xml");
        initSecurity();
    }

    @Override
    public Class<? extends Page> getHomePage() {
        return ManageActivityPage.class;
    }

    public IActivityDAO getActivityDAO() {
        return (IActivityDAO) m_context.getBean("activityDAO");
    }

//    public IJobDAO getJobDAO() {
//        return (IJobDAO) m_context.getBean("jobDAO");
//    }

    public IUserDAO getUserDAO() {
        return (IUserDAO) m_context.getBean("userDAO");
    }

    @Override
    public Session newSession(Request request, Response response) {
        return new MetroSession(request);
    }

    private void initSecurity() {
        MetroAuthorizationStrategy tmp = new MetroAuthorizationStrategy();
        getSecuritySettings().setAuthorizationStrategy(tmp);
        getSecuritySettings().setUnauthorizedComponentInstantiationListener(tmp);
    }
}
